package com.demo.crm.springboot3security.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.demo.crm.springboot3security.dto.ModuleConfig;
import com.demo.crm.springboot3security.entity.CustomForm;
import com.demo.crm.springboot3security.entity.FormField;
import com.demo.crm.springboot3security.entity.Module;
import com.demo.crm.springboot3security.entity.enums.FieldType;
import com.demo.crm.springboot3security.mapper.ModuleMapper;
import com.demo.crm.springboot3security.service.FormLayoutService;
import com.demo.crm.springboot3security.service.ModuleService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

/**
 * 模块服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ModuleServiceImpl implements ModuleService {

    private final ModuleMapper moduleMapper;
    private final FormLayoutService formLayoutService;
    private final ObjectMapper objectMapper;

    @Override
    @Transactional
    public Module createModule(ModuleConfig config) {
        // 1. 创建模块
        Module module = new Module();
        module.setName(config.getName());
        module.setCode(config.getCode());
        module.setDescription(config.getDescription());
        module.setIcon(config.getIcon());
        module.setOrderNum(config.getOrderNum());
        module.setParentId(config.getParentId());
        module.setEnabled(true);

        // 2. 设置布局配置
        try {
            String layoutConfig = objectMapper.writeValueAsString(config.getLayout());
            module.setLayoutConfig(layoutConfig);
        } catch (JsonProcessingException e) {
            log.error("布局配置序列化失败", e);
            throw new RuntimeException("模块创建失败");
        }

        // 3. 创建关联的表单
        if (config.getForms() != null && !config.getForms().isEmpty()) {
            List<CustomForm> forms = new ArrayList<>();
            for (ModuleConfig.FormConfig formConfig : config.getForms()) {
                CustomForm form = createForm(formConfig);
                form.setModule(module);
                forms.add(form);
            }
            module.setForms(forms);
        }
        moduleMapper.insert(module);
        return module;
    }

    @Override
    @Transactional
    public Module updateModule(Long moduleId, ModuleConfig config) {
        Optional<Module> opt = Optional.ofNullable(moduleMapper.selectOneById(moduleId));
        if (opt.isEmpty()) throw new RuntimeException("模块不存在");
        Module module = opt.get();
        // 1. 更新基本信息
        module.setName(config.getName());
        module.setDescription(config.getDescription());
        module.setIcon(config.getIcon());
        module.setOrderNum(config.getOrderNum());

        // 2. 更新布局配置
        try {
            String layoutConfig = objectMapper.writeValueAsString(config.getLayout());
            module.setLayoutConfig(layoutConfig);
        } catch (JsonProcessingException e) {
            log.error("布局配置序列化失败", e);
            throw new RuntimeException("模块更新失败");
        }

        // 3. 更新关联的表单
        if (config.getForms() != null) {
            // 删除不再使用的表单
            module.getForms().removeIf(form -> config.getForms().stream()
                    .noneMatch(fc -> fc.getCode().equals(form.getCode())));

            // 更新或创建表单
            for (ModuleConfig.FormConfig formConfig : config.getForms()) {
                CustomForm existingForm = module.getForms().stream()
                        .filter(f -> f.getCode().equals(formConfig.getCode()))
                        .findFirst()
                        .orElse(null);

                if (existingForm != null) {
                    updateForm(existingForm, formConfig);
                } else {
                    CustomForm newForm = createForm(formConfig);
                    newForm.setModule(module);
                    module.getForms().add(newForm);
                }
            }
        }

        moduleMapper.update(module);
        return module;
    }

    @Override
    @Transactional
    public void deleteModule(Long moduleId) {
        Optional<Module> opt = Optional.ofNullable(moduleMapper.selectOneById(moduleId));
        if (opt.isEmpty()) throw new RuntimeException("模块不存在");
        moduleMapper.deleteById(moduleId);
    }

    @Override
    public Module getModule(Long moduleId) {
        Optional<Module> opt = Optional.ofNullable(moduleMapper.selectOneById(moduleId));
        if (opt.isEmpty()) throw new RuntimeException("模块不存在");
        return opt.get();
    }

    @Override
    public Page<Module> listModules(int page, int size) {
        return moduleMapper.paginate(page, size, QueryWrapper.create());
    }

    @Override
    public List<Module> getModuleTree() {
        List<Module> allModules = moduleMapper.selectAll();
        return buildModuleTree(allModules, null);
    }

    @Override
    @Transactional
    public Module toggleModule(Long moduleId, boolean enabled) {
        Optional<Module> opt = Optional.ofNullable(moduleMapper.selectOneById(moduleId));
        if (opt.isEmpty()) throw new RuntimeException("模块不存在");
        Module module = opt.get();
        module.setEnabled(enabled);
        moduleMapper.update(module);
        return module;
    }

    /**
     * 创建表单
     */
    private CustomForm createForm(ModuleConfig.FormConfig config) {
        CustomForm form = new CustomForm();
        form.setName(config.getName());
        form.setCode(config.getCode());
        form.setDescription(config.getDescription());

        // 创建表单字段
        if (config.getFields() != null) {
            List<FormField> fields = config.getFields().stream()
                    .map(this::createFormField)
                    .collect(Collectors.toList());
            form.setFields(fields);
        }

        // 设置表单布局
        if (config.getLayout() != null) {
            try {
                String layoutConfig = objectMapper.writeValueAsString(config.getLayout());
                form.setLayoutConfig(layoutConfig);
            } catch (JsonProcessingException e) {
                log.error("表单布局配置序列化失败", e);
                throw new RuntimeException("表单创建失败");
            }
        }

        return form;
    }

    /**
     * 更新表单
     */
    private void updateForm(CustomForm form, ModuleConfig.FormConfig config) {
        form.setName(config.getName());
        form.setDescription(config.getDescription());

        // 更新字段
        if (config.getFields() != null) {
            // 删除不再使用的字段
            form.getFields().removeIf(field -> config.getFields().stream()
                    .noneMatch(fc -> fc.getCode().equals(field.getCode())));

            // 更新或创建字段
            for (ModuleConfig.FieldConfig fieldConfig : config.getFields()) {
                FormField existingField = form.getFields().stream()
                        .filter(f -> f.getCode().equals(fieldConfig.getCode()))
                        .findFirst()
                        .orElse(null);

                if (existingField != null) {
                    updateFormField(existingField, fieldConfig);
                } else {
                    FormField newField = createFormField(fieldConfig);
                    newField.setForm(form);
                    form.getFields().add(newField);
                }
            }
        }

        // 更新布局
        if (config.getLayout() != null) {
            try {
                String layoutConfig = objectMapper.writeValueAsString(config.getLayout());
                form.setLayoutConfig(layoutConfig);
            } catch (JsonProcessingException e) {
                log.error("表单布局配置序列化失败", e);
                throw new RuntimeException("表单更新失败");
            }
        }
    }

    /**
     * 创建表单字段
     */
    private FormField createFormField(ModuleConfig.FieldConfig config) {
        FormField field = new FormField();
        field.setName(config.getName());
        field.setCode(config.getCode());
        field.setType(FieldType.valueOf(config.getType()));
        field.setLabel(config.getLabel());
        field.setPlaceholder(config.getPlaceholder());
        field.setRequired(config.isRequired());
        field.setOrderNum(config.getOrderNum());
        field.setDefaultValue(config.getDefaultValue());
        field.setHelpText(config.getHelpText());

        // 设置选项
        if (config.getOptions() != null) {
            try {
                String options = objectMapper.writeValueAsString(config.getOptions());
                field.setOptions(options);
            } catch (JsonProcessingException e) {
                log.error("字段选项序列化失败", e);
                throw new RuntimeException("字段创建失败");
            }
        }

        // 设置验证规则
        if (config.getValidation() != null) {
            try {
                String validation = objectMapper.writeValueAsString(config.getValidation());
                field.setValidation(validation);
            } catch (JsonProcessingException e) {
                log.error("字段验证规则序列化失败", e);
                throw new RuntimeException("字段创建失败");
            }
        }

        // 设置样式配置
        if (config.getStyle() != null) {
            try {
                String styleConfig = objectMapper.writeValueAsString(config.getStyle());
                field.setStyleConfig(styleConfig);
            } catch (JsonProcessingException e) {
                log.error("字段样式配置序列化失败", e);
                throw new RuntimeException("字段创建失败");
            }
        }

        return field;
    }

    /**
     * 更新表单字段
     */
    private void updateFormField(FormField field, ModuleConfig.FieldConfig config) {
        field.setName(config.getName());
        field.setLabel(config.getLabel());
        field.setPlaceholder(config.getPlaceholder());
        field.setRequired(config.isRequired());
        field.setOrderNum(config.getOrderNum());
        field.setDefaultValue(config.getDefaultValue());
        field.setHelpText(config.getHelpText());

        // 更新选项
        if (config.getOptions() != null) {
            try {
                String options = objectMapper.writeValueAsString(config.getOptions());
                field.setOptions(options);
            } catch (JsonProcessingException e) {
                log.error("字段选项序列化失败", e);
                throw new RuntimeException("字段更新失败");
            }
        }

        // 更新验证规则
        if (config.getValidation() != null) {
            try {
                String validation = objectMapper.writeValueAsString(config.getValidation());
                field.setValidation(validation);
            } catch (JsonProcessingException e) {
                log.error("字段验证规则序列化失败", e);
                throw new RuntimeException("字段更新失败");
            }
        }

        // 更新样式配置
        if (config.getStyle() != null) {
            try {
                String styleConfig = objectMapper.writeValueAsString(config.getStyle());
                field.setStyleConfig(styleConfig);
            } catch (JsonProcessingException e) {
                log.error("字段样式配置序列化失败", e);
                throw new RuntimeException("字段更新失败");
            }
        }
    }

    /**
     * 构建模块树
     */
    private List<Module> buildModuleTree(List<Module> modules, Long parentId) {
        return modules.stream()
                .filter(module -> {
                    if (parentId == null) {
                        return module.getParentId() == null;
                    }
                    return parentId.equals(module.getParentId());
                })
                .map(module -> {
                    List<Module> children = buildModuleTree(modules, module.getId());
                    if (!children.isEmpty()) {
                        module.setForms(null); // 避免数据量过大
                    }
                    return module;
                })
                .collect(Collectors.toList());
    }
}